package com.stox.ui.javafx.charting.view;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import javafx.stage.Screen;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import com.stox.client.CachingBarClient;
import com.stox.dto.AbstractModel;
import com.stox.dto.intf.AbstractModelNavigable;
import com.stox.ui.javafx.charting.model.plot.AbstractPrimaryPlot;
import com.stox.ui.javafx.charting.model.plot.BarPrimaryPlot;
import com.stox.ui.javafx.core.widget.StoxStage;

@Component
public class ChartingViewDisplayHelper {

	@Autowired
	private CachingBarClient barClient;
	
	@Autowired
	private ApplicationContext applicationContext;
	
	@SuppressWarnings("unchecked")
	public void displaySingle(AbstractModelNavigable<? extends Collection<AbstractModel>> abstractModelNavigable){
		Collection<AbstractModel> models = abstractModelNavigable.get();
		
		if(null == ChartingView.getSelectedChartingView()){
			applicationContext.getBean(ChartingView.class);
		}
		
		ChartingView chartingView = ChartingView.getSelectedChartingView();
		if(null != models && !models.isEmpty()){
			Iterator<AbstractModel> iterator = models.iterator();
			chartingView.getPrimaryChart().setFrontPlot(createPrimaryPlot(iterator.next(), chartingView));
			chartingView.open();
			chartingView.update();
			
			while(iterator.hasNext()){
				new Thread(){
					public void run() {
						chartingView.getPrimaryChart().addPlot(createPrimaryPlot(iterator.next(), chartingView));
						chartingView.update();
					};
				}.start();
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	public void display(AbstractModelNavigable<? extends Collection<AbstractModel>> abstractModelNavigable){
		
		Collection<AbstractModel> models = abstractModelNavigable.get();
		
		if(1 == models.size() && null != ChartingView.getSelectedChartingView()){
			ChartingView selectedChartingView = ChartingView.getSelectedChartingView();
			selectedChartingView.setAbstractModelNavigable(abstractModelNavigable);
			selectedChartingView.getPrimaryChart().setFrontPlot(createPrimaryPlot(models.iterator().next(), selectedChartingView));
			selectedChartingView.update();
			return;
		}
		
		createChartingViews(abstractModelNavigable);
		
		int count = ChartingView.getChartingViews().size();
		int rows = 1;
		int columns = 1;
		
		while((rows*columns) < count){
			rows++;
			if((rows*columns) < count){
				columns++;
			}
		}
		
		for(int i = 0; i < count; i++){
			ChartingView chartingView = ChartingView.getChartingViews().get(i);
			setSize(chartingView, count, i+1, rows, columns);
			setPosition(chartingView, count, i+1, rows, columns);
			chartingView.open();
			chartingView.update();
		}
	}
	
	@SuppressWarnings("unchecked")
	private List<ChartingView> createChartingViews(AbstractModelNavigable<? extends Collection<AbstractModel>> abstractModelNavigable){
		Collection<AbstractModel> models = abstractModelNavigable.get();
		List<ChartingView> chartingViews = new ArrayList<ChartingView>(models.size());
		for(AbstractModel model : models){
			ChartingView chartingView = applicationContext.getBean(ChartingView.class);
			chartingView.setAbstractModelNavigable(abstractModelNavigable);
			chartingView.getPrimaryChart().setFrontPlot(createPrimaryPlot(model, chartingView));
			chartingViews.add(chartingView);
		}
		return chartingViews;
	}
	
	@SuppressWarnings("rawtypes")
	private AbstractPrimaryPlot createPrimaryPlot(AbstractModel model, ChartingView view){
		BarPrimaryPlot barPrimaryPlot = (BarPrimaryPlot)applicationContext.getBean("barPrimaryPlot", model);
		//barPrimaryPlot.setData(barClient.findByScripId(model.getId(), view.getSpanType(), new Date(), view.getDefaultBars()));
		return barPrimaryPlot;
	}
	
	private void setSize(ChartingView view, int count, int index, int rows, int columns) {
		double width = StoxStage.getInstance().getContentPane().getWidth();
		double height = StoxStage.getInstance().getContentPane().getHeight();
		double x = Screen.getPrimary().getVisualBounds().getWidth()/5;
		if(x < width/2) {
			width -= x;
		}
		
		height = height/rows;
		width = width/columns;
		if(index == count){
			width += ((rows*columns)-index)*width;
		}
		view.setPrefWidth(width);
		view.setPrefHeight(height);
	}
	
	private void setPosition(ChartingView view, int count, int index, int rows, int columns) {
		double x = Screen.getPrimary().getVisualBounds().getWidth()/5;
		double y = StoxStage.getInstance().getContentPane().getLayoutY();
		double width = StoxStage.getInstance().getContentPane().getWidth() - x;
		double height = StoxStage.getInstance().getContentPane().getHeight();

		height = height/rows;
		width = width/columns;
		
		int row = 1;
		int column = 1;
		int counter = 1;
		boolean shouldBreak = false;
		for(int i = 1; i <= rows; i++){
			for(int j = 1; j <= columns; j++){
				if(counter == index){
					row = i;
					column = j;
					shouldBreak = true;
					break;
				}
				counter++;
			}
			if(shouldBreak){
				break;
			}
		}
		
		view.setLayoutX(x+(column-1)*width);
		view.setLayoutY(y+(row-1)*height);
	} 
	
}
